package gmomo;

import gmomo.ssl.GMoMoSSLSocketFactory;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.proxy.ProxyInfo.ProxyType;

public class GMoMoConfig {

	private Properties prop;
	private ConnectionConfiguration config;
	
	private Map<String, ProxyType> proxyValue;
	private Map<String, SecurityMode> securityModes;
	
	static public ConnectionConfiguration load(String filename) throws FileNotFoundException, IOException {
		GMoMoConfig config = new GMoMoConfig();
		config.loadConfig(filename);
		return config.loadConnectionConfiguration();
	}
	
	private GMoMoConfig () {
		setProxyValues();
		setSecurityMode();
	}
	
	private void loadConfig(String filename) throws FileNotFoundException, IOException {
		prop = new Properties();
		prop.load(new FileReader(filename));
	}
	
	private ConnectionConfiguration loadConnectionConfiguration() {
		
		String host = getHost();
		int port = getPort();
		boolean isForcePort = isForcePort();
		if ( isForcePort )
			port = 5223;
		String serviceName = getServiceName();
		
		ProxyInfo proxy = null;
		ProxyType proxyType = getProxy();
		String pHost = getProxyHost();
		int pPort = getProxyPort();
		String pUser = getProxyUID();
		String pPass = getProxyPwd();
		if ( proxyType == ProxyType.NONE )
			proxy = ProxyInfo.forNoProxy();
		else if ( getProxy() == ProxyType.HTTP )
			proxy = ProxyInfo.forHttpProxy(pHost, pPort, pUser, pPass);
		else if ( getProxy() == ProxyType.SOCKS4 )
			proxy = ProxyInfo.forSocks4Proxy(pHost, pPort, pUser, pPass);
		else if ( getProxy() == ProxyType.SOCKS5 )
			proxy = ProxyInfo.forSocks5Proxy(pHost, pPort, pUser, pPass);
		
		config = new ConnectionConfiguration(host, port, serviceName, proxy);
		
		boolean isCompressionEnabled = isCompressionEnabled();
		config.setCompressionEnabled( isCompressionEnabled );
		
		boolean isSASLAuthenticationEnabled = isSASLAuthenticationEnabled();
		config.setSASLAuthenticationEnabled( isSASLAuthenticationEnabled );
		
		SecurityMode securityMode = getSecurityMode();
		if ( isForcePort ) {
			config.setSecurityMode(SecurityMode.enabled);
			config.setSocketFactory(GMoMoSSLSocketFactory.getDefault());
		}else {
			config.setSecurityMode(securityMode);
		}
		
		return config;
	}
	
	private void setProxyValues() {
		proxyValue = new HashMap<String, ProxyType>();
		proxyValue.put("none", ProxyType.NONE);
		proxyValue.put("http", ProxyType.HTTP);
		proxyValue.put("socks4", ProxyType.SOCKS4);
		proxyValue.put("socks5", ProxyType.SOCKS5);
	}
	
	private void setSecurityMode() {
		securityModes = new HashMap<String, SecurityMode>();
		securityModes.put("disabled", SecurityMode.disabled);
		securityModes.put("enabled", SecurityMode.enabled);
		securityModes.put("required", SecurityMode.required);
	}
	
	private String getHost() {
		String host = prop.getProperty("host");
		return host==null?"talk.google.com":host;
	}
	
	private int getPort() {
		String strPort = prop.getProperty("port");
		try {
			return Integer.parseInt(strPort);
		}catch (Exception e) {
			return 5222;
		}
	}
	
	private boolean isForcePort() {
		String strIsForcePort = prop.getProperty("force");
		if ( strIsForcePort == null )
			return false;
		return strIsForcePort.equalsIgnoreCase("true")?true:false;
	}
	
	private String getServiceName() {
		String serviceName = prop.getProperty("serviceName");
		return serviceName==null?"gmail.com":serviceName;
	}
	
	private ProxyType getProxy() {
		String proxy = prop.getProperty("proxy");
		if ( proxy == null || proxyValue.get(proxy.toLowerCase()) == null )
			return proxyValue.get("none");
		return proxyValue.get(proxy.toLowerCase());
	}
	
	private String getProxyHost() {
		String proxyHost = prop.getProperty("proxy_host");
		return proxyHost==null?"":proxyHost;
	}
	
	private int getProxyPort() {
		String strProxyPort = prop.getProperty("proxy_port");
		try {
			return Integer.parseInt(strProxyPort);
		}catch (Exception e) {
			return 0;
		}
	}
	
	private String getProxyUID() {
		String proxyUID = prop.getProperty("proxy_userid");
		return proxyUID==null?"":proxyUID;
	}
	
	private String getProxyPwd() {
		String proxyPwd = prop.getProperty("proxy_pwd");
		return proxyPwd==null?"":proxyPwd;
	}
	
	private boolean isCompressionEnabled() {
		String strIsCompressionEnabled = prop.getProperty("setCompressionEnabled");
		if ( strIsCompressionEnabled == null )
			return false;
		return strIsCompressionEnabled.equalsIgnoreCase("true")?true:false;
	}
	
	private boolean isSASLAuthenticationEnabled() {
		String strIsSASLAuthenticationEnabled = prop.getProperty("setSASLAuthenticationEnabled");
		if ( strIsSASLAuthenticationEnabled == null )
			return false;
		return strIsSASLAuthenticationEnabled.equalsIgnoreCase("true")?true:false;
	}
	
	private SecurityMode getSecurityMode() {
		String securityMode = prop.getProperty("setSecurityMode");
		if ( securityMode == null || securityModes.get(securityMode.toLowerCase()) == null )
			return securityModes.get("disabled");
		return securityModes.get(securityMode.toLowerCase());
	}
	
}//end of class GMoMoConfig
